import React, {
	Component,
	useState,
	useContext,
	useReducer,
	useEffect,
} from "react";
import { AppContext } from "./index.js";
// 类组件
class App extends Component {
	state = {
		number: 0,
	};
	render() {
		return (
			<div
				onClick={() => {
					this.setState({ number: 100 });
				}}
			>
				<AppContext.Consumer>
					{({ name }) => {
						return <h1>{name}</h1>;
					}}
				</AppContext.Consumer>
			</div>
		);
	}
}

// 函数组件 主流
function App2() {
	// 1. const [状态, 修改状态的方法] = useState(状态初始值);
	const [number, setNumber] = useState(0);
	// 2. 可以拿到 父级Provider传递的结果 相当于class的 Consumer
	const context = useContext(AppContext);
	// 3. useReducer 另一个状态管理的解决方案 升级版的useState
	//    const [状态, 修改状态的方法] =useReducer(reducer函数, 初始状态);
	//    state 原始状态 action 是 dispatch的参数
	//    基本类型
	//    引用类型 的赋值操作 其实改变的是堆内存里的值
	//    在React里 如果直接修改引用类型 React很有可能监听不到变化导致视图为更新 React监听的是引用地址
	const reducer = (state, action) => {
		switch (action.type) {
			case "SET_COUNT":
				state.count = action.data;
				break;
			default:
				break;
		}
		return JSON.parse(JSON.stringify(state)); // 所以需要 返回了一个新的引用地址
	};
	const [state, dispatch] = useReducer(reducer, { count: 0 });
	// 4. useEffect 副作用钩子 用来代替 class中的 生命周期
	// didMount didUpdate didUnmount
	useEffect(() => {
		// 首次进入页面
		// 状态更新的时候
		console.log("执行了");
	});
	useEffect(() => {
		// 只有首次进入执行
		console.log("2执行了");
	}, []);
	useEffect(() => {
		// 首次进入执行
		// number更新的时候执行
		console.log("3执行了");
	}, [number]);
	useEffect(() => {
		return () => {
			// 当组件销毁的时候执行
			console.log("销毁了");
		};
	}, []);
	return (
		<div>
			{state.count}
			<button
				onClick={() => {
					dispatch({ type: "SET_COUNT", data: state.count + 1 });
				}}
			>
				count++
			</button>

			{/* {number} {context.name}
			<button
				onClick={() => {
					// setNumber(number + 1);
					setNumber(prev => {
						// prev 上一次的结果
						// 当下次结果依赖于上一次的结果
						return prev + 1;
					});
				}}
			>
				加
			</button> */}
		</div>
	);
}
// 区别
// 函数组件没有 this  没有状态 没有生命周期  是个纯函数组件 （不存在副作用的函数，就是给定输入
// 输出可以确定的组件，副作用就是比如 异步 接口 事件 等结果不确定的东西就叫做副作用，纯函数组件不
// 可以写副作用代码）
// 什么是hooks
// 16.7之前的函数组件都是纯函数组件 16.7之后hooks的出现可以让 纯函数组件拥有 状态和生命周期

export default App2;
